package logic

import (
	"fmt"
	"svr/src/db"
	"svr/src/eor"
	"svr/src/internal/sdk"
	"svr/src/msg"
	"time"
)

type AccountManager struct {
	Dm *sdk.DataModelRdsSql
}

const StartId = uint64(10000)

var instance *AccountManager

func GetAccountManager() *AccountManager {
	if instance == nil {
		instance = &AccountManager{}
		instance.Dm = sdk.CreateDataModelRdsSql("account", "id", 0, &db.Account{}, func(data interface{}) interface{} {
			ac := data.(*db.Account)
			return ac.Id
		})
		instance.Dm.AddUniqueKey("name", func(data interface{}) interface{} {
			ac := data.(*db.Account)
			return ac.Name
		})
		instance.Dm.SetStartId(StartId)
		instance.Dm.SetCreateTime = func(data interface{}) {
			ac := data.(*db.Account)
			now := time.Now()
			ac.CreatedAt = now
			ac.UpdatedAt = now
		}
		instance.Dm.SetUpdateTime = func(data interface{}) {
			ac := data.(*db.Account)
			now := time.Now()
			ac.UpdatedAt = now
		}
	}
	return instance
}

const epos_RegisterAccount = "AccountManager|RegisterAccount"

func (am *AccountManager) RegisterAccount(name, pwd string, msgA *msg.AccountRegistA) *msg.Error {
	ac, mer := am.GetAccount(name)
	if mer != nil {
		return mer
	}
	if ac != nil {
		str := fmt.Sprintf("Account:%s is existed.", name)
		msgA.Err = eor.NewErr(msg.ErrCode_Err_AccountRegister, epos_RegisterAccount, 1, str)
		return nil
	}
	//没找到，可以创建
	ac = &db.Account{Name: name, Password: pwd}
	id, lock, mer := am.Dm.GetNextId()
	if mer != nil {
		return mer
	}
	if lock == nil {
		return eor.NewErr(msg.ErrCode_Err_RedisLock, epos_RegisterAccount, "2")
	}
	defer db.UnlockKey(lock)
	if id != 0 {
		ac.Id = id
	}
	return am.Dm.CreateData(ac)
}

func (am *AccountManager) GetAccount(name string) (*db.Account, *msg.Error) {
	ac := &db.Account{}
	isFind, err := am.Dm.FindData("name", name, ac)
	if err != nil {
		return nil, err
	}
	if isFind {
		return ac, nil
	}
	return nil, nil
}

const epos_AccountLogin = "AccountManager|AccountLogin"

func (am *AccountManager) AccountLogin(name, pwd string, msgA *msg.AccountLoginA) *msg.Error {
	ac, mer := am.GetAccount(name)
	// logs.Debugf("AccountLogin ", name, pwd, ac, mer)
	if mer != nil {
		return mer
	}
	if ac == nil {
		mer := eor.NewErr(msg.ErrCode_Err_AccountLogin, epos_AccountLogin, "1", "Account:", name, " is not existed.")
		msgA.Err = mer
		return nil
	}
	if ac.Password != pwd {
		mer := eor.NewErr(msg.ErrCode_Err_AccountLogin, epos_AccountLogin, "2", "Account:", name, " password is error.")
		msgA.Err = mer
		return nil
	}
	return nil
}

func (am *AccountManager) AccountLoginEnter(name, pwd string) (*msg.Error, *msg.Error, uint64) {
	ac, mer := am.GetAccount(name)
	// logs.Debugf("AccountLogin ", name, pwd, ac, mer)
	if mer != nil {
		return mer, nil, 0
	}
	if ac == nil {
		mer := eor.NewErr(msg.ErrCode_Err_AccountLogin, epos_AccountLogin, "1", "Account:", name, " is not existed.")
		return nil, mer, 0
	}
	if ac.Password != pwd {
		mer := eor.NewErr(msg.ErrCode_Err_AccountLogin, epos_AccountLogin, "2", "Account:", name, " password is error.")
		return nil, mer, 0
	}
	return nil, nil, ac.Id
}
func (am *AccountManager) RegisterAccountEnter(name, pwd string) (*msg.Error, *msg.Error, uint64) {
	ac, mer := am.GetAccount(name)
	if mer != nil {
		return mer, nil, 0
	}
	if ac != nil {
		str := fmt.Sprintf("Account:%s is existed.", name)
		return nil, eor.NewErr(msg.ErrCode_Err_AccountRegister, epos_RegisterAccount, 1, str), 0
	}
	//没找到，可以创建
	ac = &db.Account{Name: name, Password: pwd}
	id, lock, mer := am.Dm.GetNextId()
	if mer != nil {
		return mer, nil, 0
	}
	if lock == nil {
		return eor.NewErr(msg.ErrCode_Err_RedisLock, epos_RegisterAccount, "2", "err lock"), nil, 0
	}
	defer db.UnlockKey(lock)
	if id != 0 {
		ac.Id = id
	}
	mer = am.Dm.CreateData(ac)
	return mer, nil, ac.Id
}
